// 用户控制器
import jwt from 'jsonwebtoken';
import { Op } from 'sequelize';
import User from './UserModel.js';
import { redisClient } from '../../db/index.js';
import { asyncHandler, ApiError } from '../../middleware/errorHandler.js';

// JWT密钥
const JWT_SECRET = process.env.JWT_SECRET || 'your_jwt_secret_key';
// Token过期时间（24小时）
const TOKEN_EXPIRY = 60 * 60 * 24;

export const UserController = {
    /**
     * 用户注册
     * @param {Object} req - 请求对象
     * @param {Object} res - 响应对象
     * @returns {Promise<Object>} 返回注册结果
     */
    register: asyncHandler(async (req, res) => {
        const { username, password, email, phone } = req.body;
        
        // 检查必填字段
        if (!username || !password) {
            throw ApiError.badRequest('用户名和密码不能为空');
        }
        
        // 检查用户名是否已存在
        const existingUser = await User.findOne({ where: { username } });
        if (existingUser) {
            throw ApiError.conflict('用户名已存在');
        }
        
        // 检查邮箱是否已存在
        if (email) {
            const emailExists = await User.findOne({ where: { email } });
            if (emailExists) {
                throw ApiError.conflict('邮箱已被使用');
            }
        }
        
        // 检查手机号是否已存在
        if (phone) {
            const phoneExists = await User.findOne({ where: { phone } });
            if (phoneExists) {
                throw ApiError.conflict('手机号已被使用');
            }
        }
        
        // 创建新用户
        const newUser = await User.create({
            username,
            password, // 模型中会自动加密
            email,
            phone
        });
        
        return res.status(201).json({
            success: true,
            message: '用户注册成功',
            data: {
                id: newUser.id,
                username: newUser.username,
                email: newUser.email,
                phone: newUser.phone
            }
        });
    }),

    /**
     * 用户登录
     * @param {Object} req - 请求对象
     * @param {Object} res - 响应对象
     * @returns {Promise<Object>} 返回登录结果  
     */
    login: asyncHandler(async (req, res) => {
        const { username, password } = req.body;
        
        if (!username || !password) {
            throw ApiError.badRequest('用户名和密码不能为空');
        }
        
        // 查找用户
        const user = await User.findOne({ where: { username } });
        if (!user) {
            throw ApiError.unauthorized('用户名或密码错误');
        }
        
        // 验证密码
        if (!user.validatePassword(password)) {
            throw ApiError.unauthorized('用户名或密码错误');
        }
        
        // 检查账号状态
        if (user.status !== 'active') {
            throw ApiError.forbidden('账号已被禁用，请联系客服');
        }
        
        // 生成JWT令牌
        const payload = {
            id: user.id,
            username: user.username
        };
        
        const token = jwt.sign(payload, JWT_SECRET, { expiresIn: TOKEN_EXPIRY });
        
        // 更新最后登录时间
        await user.update({ last_login: new Date() });
        
        // 存储到Redis（用于注销功能）
        await redisClient.set(`user:${user.id}`, token, { EX: TOKEN_EXPIRY });
        
        return res.json({
            success: true,
            message: '登录成功',
            data: {
                token,
                user: {
                    id: user.id,
                    username: user.username,
                    email: user.email,
                    phone: user.phone,
                    avatar: user.avatar
                }
            }
        });
    }),
    
    /**
     * 用户登出
     * @param {Object} req - 请求对象
     * @param {Object} res - 响应对象
     * @returns {Promise<Object>} 返回登出结果
     */
    logout: asyncHandler(async (req, res) => {
        const userId = req.user.id;
        
        // 从Redis中删除令牌
        await redisClient.del(`user:${userId}`);
        
        return res.json({
            success: true,
            message: '登出成功'
        });
    }),
    
    /**
     * 获取当前用户信息
     * @param {Object} req - 请求对象
     * @param {Object} res - 响应对象
     * @returns {Promise<Object>} 返回用户信息
     */
    getProfile: asyncHandler(async (req, res) => {
        const userId = req.user.id;
        
        const user = await User.findByPk(userId, {
            attributes: { exclude: ['password'] }
        });
        
        if (!user) {
            throw ApiError.notFound('用户不存在');
        }
        
        return res.json({
            success: true,
            data: user
        });
    }),
    
    /**
     * 更新用户信息
     * @param {Object} req - 请求对象
     * @param {Object} res - 响应对象
     * @returns {Promise<Object>} 返回更新结果
     */
    updateProfile: asyncHandler(async (req, res) => {
        const userId = req.user.id;
        const { email, phone, avatar } = req.body;
        
        const user = await User.findByPk(userId);
        if (!user) {
            throw ApiError.notFound('用户不存在');
        }
        
        // 检查邮箱是否已被其他用户使用
        if (email && email !== user.email) {
            const emailExists = await User.findOne({ 
                where: { 
                    email,
                    id: { [Op.ne]: userId } 
                } 
            });
            
            if (emailExists) {
                throw ApiError.conflict('邮箱已被其他用户使用');
            }
        }
        
        // 检查手机号是否已被其他用户使用
        if (phone && phone !== user.phone) {
            const phoneExists = await User.findOne({ 
                where: { 
                    phone,
                    id: { [Op.ne]: userId } 
                } 
            });
            
            if (phoneExists) {
                throw ApiError.conflict('手机号已被其他用户使用');
            }
        }
        
        // 更新用户信息
        const updatedFields = {};
        
        if (email) updatedFields.email = email;
        if (phone) updatedFields.phone = phone;
        if (avatar) updatedFields.avatar = avatar;
        
        await user.update(updatedFields);
        
        return res.json({
            success: true,
            message: '用户信息更新成功',
            data: {
                id: user.id,
                username: user.username,
                email: user.email,
                phone: user.phone,
                avatar: user.avatar
            }
        });
    }),
    
    /**
     * 修改密码
     * @param {Object} req - 请求对象
     * @param {Object} res - 响应对象
     * @returns {Promise<Object>} 返回修改结果
     */
    changePassword: asyncHandler(async (req, res) => {
        const userId = req.user.id;
        const { oldPassword, newPassword } = req.body;
        
        if (!oldPassword || !newPassword) {
            throw ApiError.badRequest('原密码和新密码不能为空');
        }
        
        const user = await User.findByPk(userId);
        if (!user) {
            throw ApiError.notFound('用户不存在');
        }
        
        // 验证原密码
        if (!user.validatePassword(oldPassword)) {
            throw ApiError.unauthorized('原密码不正确');
        }
        
        // 更新密码
        await user.update({ password: newPassword });
        
        // 使当前token失效，强制重新登录
        await redisClient.del(`user:${userId}`);
        
        return res.json({
            success: true,
            message: '密码修改成功，请重新登录'
        });
    })
} 